﻿//////////////////////////////////////////////////
//                 Maruader.cs                  //
//         Part of RebornCo by kaihaider        //
//////////////////////////////////////////////////
using System.Threading.Tasks;
using ff14bot;
using ff14bot.Enums;
using ff14bot.Managers;
using ff14bot.Objects;
using RebornCo.Settings;
using RebornCo.Helpers;
using TreeSharp;

namespace RebornCo.Rotations
{
    public class Marauder : RebornCoRoutine
    {
        public override void OnInitialize()
        {
            WantHealing = false;
            WindowSettings = new MarauderSetting();
        }
        public static MarauderSetting MarauderSettings
        {
            get { return WindowSettings as MarauderSetting; }
        }
        public sealed override ClassJobType[] Class
        {
            get
            {
                return new [] 
                { 
                   ClassJobType.Marauder, ClassJobType.Warrior
                };
            }
        }
        [Behavior(BehaviorType.PreCombatBuffs)]
        public Composite MarauderCreateBasicPreCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => MarauderBuildPreCombatBuffs());
        }
        public static async Task<bool> MarauderBuildPreCombatBuffs()
        {
            if (!IsValid()) return false;
            if (Resting)
            {
                if (!Core.Player.IsCasting && await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                if (!Core.Player.IsCasting && await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                return false;
            }
            if (MarauderSettings.CooldownsUsable && !Spell.RotationSwap &&
                await Spell.CastLock("Defiance", Core.Player, !Core.Player.HasAura("Defiance"))) return true;
            if (await Spell.BuffParty("Protect")) return true;
            if (await Spell.BuffParty("Stoneskin")) return true;
            return await CombatCompanion();
        }

        [Behavior(BehaviorType.Rest)]
        public Composite MarauderCreateBasicRest()
        {
            return new ActionRunCoroutine(ctx => DefaultRestBehavior(Core.Player.CurrentTPPercent)); 
        }


        [Behavior(BehaviorType.CombatBuffs)]
        public Composite MarauderCreateBasicCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => MarauderBuildCombatBuffs()); 
        }
        public static async Task<bool> MarauderBuildCombatBuffs()
        {
            ShouldPulse = true;

            if (!Spell.Gcd && MarauderSettings.CooldownsUsable && !Spell.RotationSwap && Spell.LastCombo == Combo.Finished
                && await Spell.CastLock("Inner Beast", Core.Player.CurrentTarget, Core.Player.HasAura("Infuriated")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }

            if (await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (Spell.GcdTime < MarauderSettings.NoneGcdWindowEnd) return false;

            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable
                && await Spell.CastLock("Defiance", Core.Player, !Spell.RotationSwap && !Core.Player.HasAura("Defiance")
                || Spell.RotationSwap && Core.Player.HasAura("Defiance")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            //dps Unchained Internal Release Berserk 
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && Spell.LastCombo == Combo.Finished && Core.Player.ClassLevel > 21
                && Spell.GetSpellData("Berserk").Cooldown.TotalSeconds > 85
                && await Spell.CastLock("Unchained", Core.Player.CurrentTarget, Core.Player.HasAura("Infuriated")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && Core.Player.ClassLevel > 21
                && await Spell.CastLock("Infuriate", Core.Player, !Core.Player.HasAura("Wrath")
                && Spell.GetSpellData("Berserk").Cooldown.TotalSeconds < 80
                && Spell.GetSpellData("Berserk").Cooldown.TotalSeconds > 71
                ))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Internal Release", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Berserk", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (WindowSettings.CooldownsUsable && Spell.Potion != null && Spell.Potion.IsValid
                && Spell.Potion.CanUse(Core.Player) && Spell.Potion.Name.Equals(WindowSettings.PotionName))
            {
                Spell.Potion.UseItem(Core.Player);
                if (WindowSettings.PotionForce) Spell.UsedNoneGcd = true;
            }
            //tank Inner Beast Vengeance Bloodbath 
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Vengeance", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Bloodbath", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Invigorate", Core.Player, Core.Player.CurrentTPPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Eye for an Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Foresight", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Holmgang", Core.Player, Core.Player.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Blood for Blood", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Thrill of Battle", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Quelling Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Hawk's Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Raging Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Keen Flurry", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Convalescence", Core.Player, Core.Player.CurrentHealthPercent < 70))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Second Wind", Core.Player, Core.Player.CurrentHealthPercent < 40))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Awareness", Core.Player, Core.Player.CurrentHealthPercent < 30))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.CooldownsUsable && await Spell.CastLock("Featherfoot", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }


        [Behavior(BehaviorType.Pull)]
        public Composite MarauderCreateBasicPull()
        {
            return new ActionRunCoroutine(ctx => MarauderBuildPullBehavior()); 
        }
        public static async Task<bool> MarauderBuildPullBehavior()
        {
            if (Core.Player.CurrentTarget != null && !Core.Player.CurrentTarget.CanAttack || !IsValid()) return false;
            ShouldPulse = true;
            if (Target.TargetChanged && MarauderSettings.OpenerUse && (!MarauderSettings.OpenerPartyOnly || PartyManager.NumMembers>2))
            {
                Target.TargetChanged = false;
                Spell.Opener = true;
                OpenExtra = false;
                ff14bot.Helpers.Logging.Write("[RebornCo] Target Has Changed - Resetting Opener");
            }
            await Target.EnsureValidTarget();
            if (await Movement.PullMove(Core.Player.CurrentTarget)) return true;
            //Core.Player.CurrentTarget.Interact();
            if (MarauderSettings.BuffedTomahawk && Core.Player.CurrentTarget!= null && 15 > Core.Player.CurrentTarget.Distance2D()
                    && Core.Player.CurrentTarget.Distance2D() > Movement.MeleeRange + 5 && Actionmanager.CurrentActions.ContainsKey("Tomahawk"))
            {
                if (await Spell.CastLock("Infuriate", Core.Player, true)) return true;
                if (await Spell.CastLock("Unchained", Core.Player, true)) return true;
                if (await Spell.CastLock("Berserk", Core.Player, true)) return true;
                if (await Spell.CastLock("Internal Release", Core.Player, true)) return true;
                if (await Spell.CastLock("Tomahawk", Core.Player.CurrentTarget,
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Infuriate") || !Actionmanager.CurrentActions.ContainsKey("Infuriate")) &&
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Unchained") || !Actionmanager.CurrentActions.ContainsKey("Unchained")) &&
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Berserk") || !Actionmanager.CurrentActions.ContainsKey("Berserk")) &&
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Internal Release") || !Actionmanager.CurrentActions.ContainsKey("Internal Release"))
                    )) return true;
                if (!Extensions.DoubleCastPreventionDict.Contains(null, "Tomahawk"))
                    return false;
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.Maim && (Core.Player.ClassLevel > 49
                || Core.Player.ClassLevel > 37 && StormsPath))
            {
                if (await Spell.Cast("Storm's Eye", Core.Player.CurrentTarget,
                    StormsEye && (Spell.CachedCombo == Combo.StormsEye || !StormsPath
                        || Spell.CachedCombo == Combo.Flushed && !(Core.Player.CurrentTarget.HasAura("Storm's Eye", false, MarauderSettings.StormsEyeClip) || Core.Player.CurrentTarget.HasAura("Dancing Edge", false, MarauderSettings.StormsEyeClip))))) return true;
                if (await Spell.Cast("Storm's Path", Core.Player.CurrentTarget,
                    StormsPath && (Spell.CachedCombo == Combo.StormsPath || Spell.CachedCombo == Combo.Flushed))) return true;
                if (StormsEye || StormsPath)
                    return false;
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.SkullSunder && Core.Player.ClassLevel > 29 && Actionmanager.CurrentActions.ContainsKey("Butcher's Block"))
            {
                return await Spell.Cast("Butcher's Block", Core.Player.CurrentTarget);
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.HeavySwing && Core.Player.ClassLevel > 3)
            {
                if (await Spell.Cast("Maim", Core.Player.CurrentTarget, Spell.CachedCombo == Combo.Maim
                    || !Spell.Opener && Spell.CachedCombo == Combo.Flushed
                    && ((Core.Player.ClassLevel < 37 || !StormsPath && !StormsEye) && !Core.Player.HasAura("Maim", false, MarauderSettings.MaimClip)
                        || Core.Player.ClassLevel > 49 && StormsEye
                        && !(Core.Player.CurrentTarget.HasAura("Storm's Eye", false, MarauderSettings.StormsEyeClip) || Core.Player.CurrentTarget.HasAura("Dancing Edge", false, MarauderSettings.StormsEyeClip))
                        || Core.Player.ClassLevel > 37 && StormsPath
                            && !Core.Player.CurrentTarget.HasAura("Storm's Path", false, MarauderSettings.StormsPathClip)))) return true;
                return await Spell.Cast("Skull Sunder", Core.Player.CurrentTarget, Spell.CachedCombo == Combo.Flushed || Spell.CachedCombo == Combo.SkullSunder);
            }
            return await Spell.PullCast("Heavy Swing", Core.Player.CurrentTarget);

        }

        [Behavior(BehaviorType.Combat)]
        public Composite MarauderCreateBasicCombat()
        {
            return new ActionRunCoroutine(ctx => MarauderBuildBasicCombat()); 
        }
        public static async Task<bool> MarauderBuildBasicCombat()
        {
            await Target.EnsureValidTarget();
            await Movement.MoveToTarget();
            if (Target.TargetChanged && MarauderSettings.OpenerUse && (!MarauderSettings.OpenerPartyOnly || PartyManager.NumMembers > 2))
            {
                Target.TargetChanged = false;
                Spell.Opener = true;
                OpenExtra = false;
                ff14bot.Helpers.Logging.Write("[RebornCo] Target Has Changed - Resetting Opener");
            }
            ShouldPulse = true;
            if (Core.Player.CurrentTarget != null && MovementManager.IsMoving
                && !(Core.Player.CurrentTarget.InLineOfSight() && Core.Player.CurrentTarget.Distance2D() < Movement.ObjectMeleeRange(Core.Player.CurrentTarget))) return true;
            if (!Spell.Gcd && Spell.LastCombo == Combo.Maim && (Core.Player.ClassLevel > 49 
                || Core.Player.ClassLevel > 37 && StormsPath ))
            {
                if (await Spell.Cast("Storm's Eye", Core.Player.CurrentTarget,
                    StormsEye && (Spell.CachedCombo == Combo.StormsEye || !StormsPath 
                        || Spell.CachedCombo == Combo.Flushed && !(Core.Player.CurrentTarget.HasAura("Storm's Eye", false, MarauderSettings.StormsEyeClip) || Core.Player.CurrentTarget.HasAura("Dancing Edge", false, MarauderSettings.StormsEyeClip))))) return true;
                if (await Spell.Cast("Storm's Path", Core.Player.CurrentTarget,
                    StormsPath && (Spell.CachedCombo == Combo.StormsPath || Spell.CachedCombo == Combo.Flushed))) return true;
                if (StormsEye || StormsPath) 
                    return false;
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.SkullSunder && Core.Player.ClassLevel > 29 && Actionmanager.CurrentActions.ContainsKey("Butcher's Block"))
            {
                if (MarauderSettings.OpenWithExtraSs && Spell.Opener)
                {
                    if (OpenExtra && Spell.CachedCombo == Combo.Flushed)
                    {
                        OpenExtra = false;
                        Spell.Opener = false;
                        Spell.LastCombo = Combo.Finished;
                        Spell.ComboCountdown = System.DateTime.UtcNow.TimeOfDay +
                                                System.TimeSpan.FromSeconds(3);
                        return false;
                    }
                    OpenExtra = true;
                    Spell.CachedCombo = Combo.ButchersBlock;
                    Spell.ComboCountdown = System.DateTime.UtcNow.TimeOfDay +
                                            System.TimeSpan.FromSeconds(2);
                }
                Spell.Opener = false;
                return await Spell.Cast("Butcher's Block", Core.Player.CurrentTarget);
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.HeavySwing && Core.Player.ClassLevel > 3)
            {
                if (!Spell.Opener && OpenExtra)
                {
                    Spell.Opener = true;
                }
                if (await Spell.Cast("Maim", Core.Player.CurrentTarget, Spell.CachedCombo == Combo.Maim
                    || !Spell.Opener && Spell.CachedCombo == Combo.Flushed
                    && ((Core.Player.ClassLevel < 37 || !StormsPath && !StormsEye || MarauderSettings.MaimKeepActive)
                        && !Core.Player.HasAura("Maim",false,MarauderSettings.MaimClip)
                        || Core.Player.ClassLevel > 49 && StormsEye && (!StormsPath || !MarauderSettings.PreventBackToBackEyeAndPath || !Core.Player.CurrentTarget.HasAura("Storm's Path", true, 1400))
                            && !(Core.Player.CurrentTarget.HasAura("Storm's Eye", false, MarauderSettings.StormsEyeClip) || Core.Player.CurrentTarget.HasAura("Dancing Edge", false, MarauderSettings.StormsEyeClip))
                        || Core.Player.ClassLevel > 37 && StormsPath && (!StormsEye || !MarauderSettings.PreventBackToBackEyeAndPath || !Core.Player.CurrentTarget.HasAura("Storm's Eye", true, 1400))
                            && !Core.Player.CurrentTarget.HasAura("Storm's Path", false, MarauderSettings.StormsPathClip)))) return true;
                if (Spell.Opener &&
                    (Core.Player.ClassLevel < 30 || !Actionmanager.CurrentActions.ContainsKey("Butcher's Block")))
                {
                    Spell.Opener = false;
                    Spell.CachedCombo = Combo.SkullSunder;
                    Spell.ComboCountdown = System.DateTime.UtcNow.TimeOfDay +
                                            System.TimeSpan.FromSeconds(2);
                }
                return await Spell.Cast("Skull Sunder", Core.Player.CurrentTarget, Spell.CachedCombo == Combo.Flushed || Spell.CachedCombo == Combo.SkullSunder);
            }
            //aoe Overpower frontal cone - add boot setting
            //aoe Steel Cyclone hasaura Infuriated
            if (!Spell.Gcd && !Spell.Opener && await Spell.CastLock("Venomous Bite", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > MarauderSettings.MinDotHp
                        && !Core.Player.CurrentTarget.HasAura("Venomous Bite", true))) return true;
            if (!Spell.Gcd && !Spell.Opener && (Core.Player.CurrentTarget.HasAura("Storm's Eye", false, MarauderSettings.StormsEyeClip)|| Core.Player.CurrentTarget.HasAura("Dancing Edge", false, MarauderSettings.StormsEyeClip))
                && await Spell.CastLock("Fracture", Core.Player.CurrentTarget, MarauderSettings.Fracture && Core.Player.CurrentTarget != null && (Core.Player.CurrentTarget as Character) != null
                        && !(Core.Player.CurrentTarget as Character).HasAura("Fracture"))) return true;
            if (Spell.Opener && MarauderSettings.BuffedTomahawk && Core.Player.CurrentTarget != null && 15 > Core.Player.CurrentTarget.Distance2D()
    && Core.Player.CurrentTarget.Distance2D() > Movement.MeleeRange + 5 && Actionmanager.CurrentActions.ContainsKey("Tomahawk"))
            {
                if (await Spell.CastLock("Infuriate", Core.Player, true)) return true;
                if (await Spell.CastLock("Unchained", Core.Player, true)) return true;
                if (await Spell.CastLock("Berserk", Core.Player, true)) return true;
                if (await Spell.CastLock("Internal Release", Core.Player, true)) return true;
                if (await Spell.CastLock("Tomahawk", Core.Player.CurrentTarget,
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Infuriate") || !Actionmanager.CurrentActions.ContainsKey("Infuriate")) &&
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Unchained") || !Actionmanager.CurrentActions.ContainsKey("Unchained")) &&
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Berserk") || !Actionmanager.CurrentActions.ContainsKey("Berserk")) &&
                    (Extensions.DoubleCastPreventionDict.Contains(null, "Internal Release") || !Actionmanager.CurrentActions.ContainsKey("Internal Release"))
                    )) return true;
                if (!Extensions.DoubleCastPreventionDict.Contains(null, "Tomahawk"))
                    return false;
            }
            if (!Spell.Gcd && await Spell.Cast("Heavy Swing", Core.Player.CurrentTarget)) return true;
            if (!Spell.Gcd && (!Spell.Opener || !MarauderSettings.BuffedTomahawk) && await Spell.CastLock("Tomahawk", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null
                && 15 > Core.Player.CurrentTarget.Distance2D()
                && Core.Player.CurrentTarget.Distance2D() > Movement.MeleeRange + 5)) return true;
            if (Spell.GcdTime < MarauderSettings.NoneGcdWindowEnd) return false;

            if (!Spell.UsedNoneGcd && await Spell.CastLock("Mercy Stroke", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && MarauderSettings.BrutalSwing && await Spell.CastLock("Brutal Swing", Core.Player.CurrentTarget))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }

        public static bool OpenExtra, StormsPath, StormsEye;
    }
}
